/**
 * ESUI (Enterprise Simple UI)
 * Copyright 2013 Baidu Inc. All rights reserved.
 *
 * @ignore
 * @file Panel控件
 * @author otakustay
 */
define(
    function (require) {
        var u = require('underscore');
        var Control = require('./Control');
        var eoo = require('eoo');
        var painters = require('./painters');
        var esui = require('./main');

        /**
         * 通用面板
         *
         * 本身没有特别意义，仅作为一个容器存在，方便显示/隐藏等操作
         *
         * 需要特别注意的是，对面板进行`disable()`操作，并不会禁用其内部的控件，
         * 对控件进行批量禁用/启用操作，请使用{@link ViewContext#getGroup}
         * 及{@link ControlCollection}提供的相关方法
         *
         * @extends Control
         * @constructor
         */
        var Panel = eoo.create(
            Control,
            {
                /**
                 * 控件类型，始终为`"Panel"`
                 *
                 * @type {string}
                 * @readonly
                 * @override
                 */
                type: 'Panel',

                /**
                 * 获取控件的分类
                 *
                 * @return {string} 始终返回`"container"`
                 * @override
                 */
                getCategory: function () {
                    return 'container';
                },

                /**
                 * 创建控件主元素
                 *
                 * 如果初始化时提供{@link Panel#tagName}属性，则以此创建元素，
                 * 默认使用`<div>`元素
                 *
                 * @param {Object} options 构造函数传入的参数
                 * @return {HTMLElement}
                 * @protected
                 * @override
                 */
                createMain: function (options) {
                    if (!options.tagName) {
                        return this.$super([options]);
                    }
                    return document.createElement(options.tagName);
                },

                /**
                 * 初始化参数
                 *
                 * 如果初始化时提供了主元素，则使用主元素的标签名作为{@link Panel#tagName}属性
                 *
                 * @param {Object} [options] 构造函数传入的参数
                 * @protected
                 * @override
                 */
                initOptions: function (options) {
                    var properties = {};
                    u.extend(properties, options);
                    /**
                     * @property {string} tagName
                     *
                     * 指定主元素标签名
                     *
                     * 此属性仅在初始化时生效，运行期不能修改
                     *
                     * @readonly
                     */
                    properties.tagName = this.main.nodeName.toLowerCase();
                    this.setProperties(properties);
                },

                /**
                 * 重渲染
                 *
                 * @method
                 * @protected
                 * @override
                 */
                repaint: painters.createRepaint(
                    Control.prototype.repaint,
                    {
                        /**
                         * @property {string} content
                         *
                         * 面板的内容，为一个HTML片段
                         *
                         * 此属性中可包含ESUI相关的属性，在设置内容后，
                         * 会使用{@link Helper#initChildren}进行内部控件的初始化
                         */
                        name: 'content',
                        paint: function (panel, content) {
                            // 第一次刷新的时候是可能没有`content`的，
                            // 这时在`innerHTML`上就地创建控件，不要刷掉内容，
                            // 后续有要求`content`是字符串，所以不管非字符串的后果
                            if (content != null) {
                                panel.helper.disposeChildren();
                                panel.main.innerHTML = content;
                            }
                            panel.helper.initChildren();
                        }
                    }
                ),

                /**
                 * 设置内容
                 *
                 * @param {string} html 内容HTML，具体参考{@link Panel#content}属性的说明
                 */
                setContent: function (html) {
                    this.setProperties({content: html});
                },

                /**
                 * 在面板最前面追加内容
                 *
                 * @param {string} html 追加内容的HTML代码
                 */
                prependContent: function (html) {
                    addContent.call(this, html, true);
                },

                /**
                 * 在面板最后面追加内容
                 *
                 * @param {string} html 追加内容的HTML代码
                 */
                appendContent: function (html) {
                    addContent.call(this, html, false);
                },

                /**
                 * 获取样式，仅获取设置的样式，不包含外部CSS给定的
                 *
                 * @param {string} name 样式名称
                 * @return {string}
                 */
                getStyle: function (name) {
                    name = normalizeStyleName(name);
                    return this.main
                        ? this.main.style[name]
                        : '';
                },

                /**
                 * 设置样式
                 *
                 * @param {string} name 样式名称，如果只有这一个参数，则表示为整串样式
                 * @param {string} [value=""] 样式值
                 */
                setStyle: function (name, value) {
                    name = normalizeStyleName(name);
                    if (this.main) {
                        this.main.style[name] = value || '';
                    }
                }
            }
        );

        /**
         * 追加内容
         *
         * @param {string} html 追加内容的HTML代码
         * @param {boolean} isPrepend 是否加到面板最前面
         * @ignore
         */
        function addContent(html, isPrepend) {
            var main = this.main;
            var container = document.createElement('div');
            container.innerHTML = html;

            var options = u.extend({}, this.renderOptions, {
                viewContext: this.viewContext,
                parent: this
            });

            var childNodes = container.childNodes;
            var children = [];
            for (var i = 0; i < childNodes.length; i++) {
                if (isPrepend) {
                    children.unshift(childNodes[i]);
                }
                else {
                    children.push(childNodes[i]);
                }
            }

            u.each(children, function (child) {
                if (isPrepend) {
                    main.insertBefore(child, main.firstChild);
                }
                else {
                    main.appendChild(child);
                }
                esui.init(main, options);
            });

            // 直接追加到content属性，以防setContent时判断oldValue出现问题
            this.content = isPrepend ? html + this.content : this.content + html;
        }

        /**
         * 统一化样式名
         *
         * @param {string} name 样式名称
         * @return {string} 统一化后`camelCase`的样式名称
         * @ignore
         */
        function normalizeStyleName(name) {
            if (name.indexOf('-') >= 0) {
                name = name.replace(
                    /-\w/g,
                    function (word) {
                        return word.charAt(1).toUpperCase();
                    }
                );
            }

            return name;
        }

        esui.register(Panel);
        return Panel;
    }
);
